package com.inspur.edp.formserver.viewmodel.webapi;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.cef.designtime.api.dtconsistencycheck.ConsistencyCheckEventMessage;
import com.inspur.edp.das.commonmodel.util.HandleAssemblyNameUtil;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.common.ConvertUtils;
import com.inspur.edp.formserver.viewmodel.common.ValueHelpConfig;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.actioneventargs.*;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.entityeventargs.ChangingViewObjectCodeEventArgs;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.entityeventargs.RemovingViewObjectEventArgs;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.fieldeventargs.ChangingVoFieldDataTypeEventArgs;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.fieldeventargs.ChangingVoFieldLabelIdEventArgs;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.fieldeventargs.ChangingVoFieldObjectTypeEventArgs;
import com.inspur.edp.formserver.viewmodel.dtconsistencycheck.fieldeventargs.RemovingVoFieldEventArgs;
import com.inspur.edp.formserver.viewmodel.exception.ViewModelException;
import com.inspur.edp.formserver.viewmodel.i18n.VMI8nResourceUtil;
import com.inspur.edp.formserver.vmmanager.helpconfig.HelpConfigFilterSortHandler;
import com.inspur.edp.formserver.vmmanager.service.WebControllerService;
import com.inspur.edp.formserver.vmmanager.util.CheckInfoUtil;
import com.inspur.edp.formserver.vmmanager.vmdtconsistencycheckevent.VmDtConsistencyCheckEventBroker;
import com.inspur.edp.formserver.vmmanager.voguide.VoGuideUtil;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.metadata.businesstype.api.MdBizTypeMappingService;
import com.inspur.lcm.metadata.logging.LoggerDisruptorQueue;
import io.iec.edp.caf.boot.context.CAFContext;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.List;

@Path("")
@Produces(MediaType.APPLICATION_JSON)
public class VMCodeGenController {
    @Path("checkvo")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public void checkKeywords(String jsonObject) {
        WebControllerService.getInstance().checkKeywords(jsonObject);
    }

    @Path("convertBizEntity")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public String convertBizEntity(String jsonObject) {
        if (CheckInfoUtil.checkNull(jsonObject)) {
            throw new ViewModelException(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1003, null);
        }

        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode jsonNode = mapper.readTree(jsonObject);
            JsonNode bizEntityJsonNode = jsonNode.get("bizEntityJson");
            CheckInfoUtil.checkNessaceryInfo("bizEntityJson", bizEntityJsonNode);
            JsonNode bePkgNameJsonNode = jsonNode.get("bePkgName");
            CheckInfoUtil.checkNessaceryInfo("bePkgName", bePkgNameJsonNode);
            JsonNode beIdJsonNode = jsonNode.get("beId");
            CheckInfoUtil.checkNessaceryInfo("beId", beIdJsonNode);
            JsonNode voGeneratingAssemblyJsonNode = jsonNode.get("voGeneratingAssembly");
            CheckInfoUtil.checkNessaceryInfo("voGeneratingAssembly", voGeneratingAssemblyJsonNode);

            String bizEntityJson = bizEntityJsonNode.textValue();
            String bePkgName = bePkgNameJsonNode.textValue();
            String beId = beIdJsonNode.textValue();
            String voGeneratingAssembly = voGeneratingAssemblyJsonNode.textValue();

            return convertBizEntityToViewModel(bizEntityJson, bePkgName, beId, voGeneratingAssembly);
        } catch (Exception e) {
            throw new ViewModelException(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1027, e);
        }

    }


    @Path("createVoRt")
    @PUT
    public String createVoRt(String jsonObject) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode jsonNode = mapper.readTree(jsonObject);

            JsonNode basicInfoNode = jsonNode.get("basicInfo");
            CheckInfoUtil.checkNessaceryInfo("basicInfoNode", basicInfoNode);
            String voCode = basicInfoNode.get("code").textValue();
            String voName = basicInfoNode.get("name").textValue();

            JsonNode beNode = jsonNode.get("be");
            CheckInfoUtil.checkNessaceryInfo("beNode", beNode);
            GspBusinessEntity be = mapper.readValue(beNode.toString(), GspBusinessEntity.class);
            CheckInfoUtil.checkNessaceryInfo("be", be);

            GspMetadata beMetadata = VoGuideUtil.getInstance().getRtMetadata(be.getID());
            String beNameSpace = VoGuideUtil.getInstance().getVoMetaGeneratingAssembly(beMetadata);
            String bizObjectId = beMetadata.getHeader().getBizobjectID();

            JsonNode configsArrayNode = jsonNode.get("configs");
            HashMap<String, String> configMap = new HashMap<>();
            if (configsArrayNode != null && configsArrayNode.size() != 0) {
                for (JsonNode configNode : configsArrayNode) {
                    String key = configNode.get("key").textValue();
                    String value = configNode.get("value").textValue();
                    configMap.put(key, value);
                }
            }
            String billCategoryId = null;
            JsonNode billCategoryInfo = jsonNode.get("billCategoryId");
            if (CheckInfoUtil.checkNull(billCategoryInfo)) {
                billCategoryId = billCategoryInfo.textValue();
            }

            GspViewModel vo = VoGuideUtil.getInstance()
                    .createVo(be, configMap, beNameSpace, HandleAssemblyNameUtil
                            .convertToJavaPackageName(beNameSpace));
            vo.setCode(voCode);
            vo.setName(voName);
            String voId = VoGuideUtil.getInstance().saveVoRt(vo, bizObjectId, beNameSpace);
            MdBizTypeMappingService service = SpringBeanUtils.getBean(MdBizTypeMappingService.class);
            if (billCategoryId == null)
                service.save(configMap.get("billCategoryId"), voId);
            else
                service.save(billCategoryId, voId);

            return new ObjectMapper().writeValueAsString(voId);
        } catch (Exception e) {
            throw new ViewModelException(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1028, e);
        }
    }

    @Path("checkVoConfigIdRt")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public void checkVoConfigIdRt(String jsonObject) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode jsonNode = mapper.readTree(jsonObject);
            JsonNode beIdNode = jsonNode.get("beId");
            CheckInfoUtil.checkNessaceryInfo("beIdNode", beIdNode);
            String beId = beIdNode.textValue();
            CheckInfoUtil.checkNessaceryInfo("beId", beId);

            JsonNode voCodeNode = jsonNode.get("voCode");
            CheckInfoUtil.checkNessaceryInfo("voCodeNode", voCodeNode);
            String voCode = voCodeNode.textValue();
            CheckInfoUtil.checkNessaceryInfo("voCode", voCode);

            GspMetadata beMetadata = VoGuideUtil.getInstance().getRtMetadata(beId);
            String beNameSpace = VoGuideUtil.getInstance().getVoMetaGeneratingAssembly(beMetadata);
            GspViewModel vo = ConvertUtils
                    .convertToViewModel((GspBusinessEntity) beMetadata.getContent(), beNameSpace,
                            beMetadata.getHeader().getId(),
                            HandleAssemblyNameUtil.convertToJavaPackageName(beNameSpace));
            vo.setCode(voCode);
            VoGuideUtil.getInstance().checkBeforeSave(vo.getGeneratedConfigID(), vo.getId(), vo.getCode());
        } catch (Exception e) {
            throw new ViewModelException(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1029, e);
        }
    }

    @Path("handleHelpConfigFilterSort")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ValueHelpConfig handleHelpConfigFilterSortCondition(String jsonObject) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode jsonNode = mapper.readTree(jsonObject);
            JsonNode helpConfigNode = jsonNode.get("helpConfig");
            CheckInfoUtil.checkNessaceryInfo("helpConfig", helpConfigNode);
            ValueHelpConfig config = mapper.readValue(helpConfigNode.textValue(), ValueHelpConfig.class);
            JsonNode filterConditionNode = jsonNode.get("filterCondition");
            JsonNode sortConditionNode = jsonNode.get("sortCondition");
            JsonNode pathNode = jsonNode.get("path");
            HelpConfigFilterSortHandler.getInstance(config, pathNode.textValue())
                    .handleConfigFilterAndSort(
                            filterConditionNode.textValue(), sortConditionNode.textValue());
            return config;
        } catch (Exception e) {
            throw new ViewModelException(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1030, e);
        }
    }

    private String convertBizEntityToViewModel(String bizEntityJson, String bePkgName, String beId,
                                               String voGeneratingAssembly) {
        GspBusinessEntity be = null;
        try {
            be = new ObjectMapper().readValue(bizEntityJson, GspBusinessEntity.class);
            GspViewModel vm = ConvertUtils.convertToViewModel(be, bePkgName, beId, voGeneratingAssembly);
            // 联动vo的关联带出字段枚举信息
//            LinkBeUtils linkBeUtils = new LinkBeUtils();
//            linkBeUtils.LinkBeRefElements(vm);

            return new ObjectMapper().writeValueAsString(vm);
        } catch (Exception e) {
            throw new ViewModelException(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1023, e);
        }
    }


    /**
     * 删除Vo节点
     */
    @Path("vmDtConsistencyCheck/removingViewObject")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public RemovingViewObjectEventArgs removingViewObject(RemovingViewObjectEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireRemovingViewObject(args);

        if (args.getEventMessages().size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1032);
            BefConsistencyCheckMessage(args.getEventMessages(), suffix);
        }
        return args;
    }

    /**
     * 修改BizEntityCode
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingViewObjectCode")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingViewObjectCodeEventArgs changingViewObjectCode(ChangingViewObjectCodeEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingViewObjectCode(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1032);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 删除Vo 字段
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/removingVoField")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public RemovingVoFieldEventArgs removingVoField(RemovingVoFieldEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireRemovingVoField(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1033);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 修改Vo字段数据类型
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoFieldDataType")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoFieldDataTypeEventArgs changingVoFieldDataType(ChangingVoFieldDataTypeEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoFieldDataType(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1033);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 修改Vo字段objectType
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoFieldObjectType")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoFieldObjectTypeEventArgs changingVoFieldObjectType(ChangingVoFieldObjectTypeEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoFieldObjectType(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1033);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 修改Vo字段标签
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoFieldLabelId")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoFieldLabelIdEventArgs changingVoFieldLabelId(ChangingVoFieldLabelIdEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoFieldLabelId(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1033);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 修改动作编号
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoActionCode")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoActionCodeEventArgs changingVoActionCode(ChangingVoActionCodeEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoActionCode(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1034);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 修改动作参数
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoActionParams")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoActionParamsEventArgs changingVoActionParams(ChangingVoActionParamsEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoActionParams(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1034);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 修改集合类型
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoActionCollectType")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoActionCollectTypeEventArgs changingVoActionCollectType(
            ChangingVoActionCollectTypeEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoActionCollectType(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1034);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 修改动作参数
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/changingVoActionReturn")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public ChangingVoActionReturnEventArgs changingVoActionReturn(ChangingVoActionReturnEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireChangingVoActionReturn(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1034);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 修改动作参数
     *
     * @return
     */
    @Path("vmDtConsistencyCheck/deletingVoAction")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    public DeletingVoActionEventArgs deletingVoAction(DeletingVoActionEventArgs args) {
        VmDtConsistencyCheckEventBroker vmEventBroker = SpringBeanUtils.getBean(VmDtConsistencyCheckEventBroker.class);
        vmEventBroker.fireDeletingVoAction(args);

        if (args.eventMessages.size() != 0) {
            String suffix= VMI8nResourceUtil.getResourceValue(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1034);
            BefConsistencyCheckMessage(args.eventMessages, suffix);
        }
        return args;
    }

    /**
     * 控制台输出BEF Warnings
     *
     * @param messages
     */
    public void BefConsistencyCheckMessage(List<ConsistencyCheckEventMessage> messages, String
            suffix) {
        StringBuilder befWarnings = new StringBuilder();
        if (messages.size() > 0)
            messages.forEach(message -> {
                befWarnings.append(message.getMessage());
            });
        befWarnings.append(suffix);
        String currentUerId = CAFContext.current.getUserId();
        if (currentUerId == null || currentUerId.equals("")) {
            throw new ViewModelException(VoWebApiErrorCodes.GSP_VIEWOBJECT_WEBAPI_1031, null);
        }
        LoggerDisruptorQueue.publishEvent("[BEF Warning]:" + befWarnings.toString(), currentUerId);
    }
}
